package com.easylinkin.linkappapi.calculaterule.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.calculaterule.entity.CalculateConfig;
import com.easylinkin.linkappapi.calculaterule.entity.CalculateConfigAttribute;
import com.easylinkin.linkappapi.calculaterule.mapper.CalculateConfigMapper;
import com.easylinkin.linkappapi.calculaterule.service.CalculateConfigAttributeService;
import com.easylinkin.linkappapi.calculaterule.service.CalculateConfigService;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.service.CommonService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * <p>
 * 计算配置 服务实现类
 * </p>
 *
 * @author TongJie
 * @since 2020-06-17
 */
@Service
public class CalculateConfigServiceImpl extends ServiceImpl<CalculateConfigMapper, CalculateConfig> implements CalculateConfigService {


    @Resource
    private CommonService commonService;
    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;
    @Resource
    private CalculateConfigAttributeService calculateConfigAttributeService;

    private static final Logger LOGGER = LoggerFactory.getLogger(CalculateConfigServiceImpl.class);

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(CalculateConfig calculateConfig) {
        validParamRequired(calculateConfig);
        validParamFormat(calculateConfig);
        validRepeat(calculateConfig);
        calculateConfig.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        commonService.setCreateAndModifyInfo(calculateConfig);
        save(calculateConfig);
        LOGGER.info("新增计算配置：{}", calculateConfig.getName());

        List<CalculateConfigAttribute> calculateConfigAttributes = calculateConfig.getCalculateConfigAttributes();

        for (CalculateConfigAttribute calculateConfigAttribute : calculateConfigAttributes) {
            calculateConfigAttribute.setCalculateConfigId(calculateConfig.getId());
        }
        calculateConfigAttributeService.saveOrUpdateBatch(calculateConfigAttributes);
    }

    /**
     * 校验重复
     */
    private void validRepeat(CalculateConfig calculateConfig) {
        QueryWrapper<CalculateConfig> queryWrapper = new QueryWrapper();
        queryWrapper.eq("name", calculateConfig.getName());
        queryWrapper.eq("tenant_id", linkappUserContextProducer.getNotNullCurrent().getTenantId());
        List<CalculateConfig> list = baseMapper.selectList(queryWrapper);
        if (list.size() == 0) {
            return;
        }
        if (list.size() > 1) {
            throw new BusinessException("计算名称有重复");
        }
        if (StringUtils.isEmpty(calculateConfig.getId())) {
            throw new BusinessException("计算名称已存在");
        }
        if (!calculateConfig.getId().equals(list.get(0).getId())) {
            throw new BusinessException("计算名称已存在");
        }

    }


    /**
     * 校验参数必填
     */
    private void validParamRequired(CalculateConfig calculateConfig) {

        Assert.notNull(calculateConfig, "参数为空");
        Assert.isTrue(StringUtils.isNotBlank(calculateConfig.getName()), "名称为空");
        Assert.isTrue(StringUtils.isNotBlank(calculateConfig.getCode()), "编号为空");
    }

    /**
     * 校验参数格式
     */
    private void validParamFormat(CalculateConfig calculateConfig) {
        Assert.isTrue(calculateConfig.getName() == null || calculateConfig.getName().length() <= 32, "计算名称超长");
        Assert.isTrue(calculateConfig.getCode() == null || calculateConfig.getCode().length() <= 32, "计算编号超长");
    }

    @Override
    public List<CalculateConfig> getCalculateConfigs(CalculateConfig calculateConfig) {
        Assert.notNull(calculateConfig, "参数为空");
        calculateConfig.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        return baseMapper.getCalculateConfigs(calculateConfig);
    }

    @Override
    public CalculateConfig getCalculateConfig(String id) {
        return baseMapper.getCalculateConfig(id);
    }

    @Override
    public IPage<CalculateConfig> getCalculateConfigsPage(Page page, CalculateConfig calculateConfig) {
        Assert.notNull(calculateConfig, "参数为空");
        calculateConfig.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        return baseMapper.getCalculateConfigs(page, calculateConfig);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCalculateConfig(CalculateConfig calculateConfig) {
        Assert.notNull(calculateConfig, "参数为空");
        CalculateConfig originCalculateConfig = getById(calculateConfig.getId());
        Assert.notNull(originCalculateConfig, "原计算配置不存在");
        validRepeat(calculateConfig);
        validParamFormat(calculateConfig);
        commonService.setModifyInfo(calculateConfig);
        updateById(calculateConfig);

        List<CalculateConfigAttribute> calculateConfigAttributes = calculateConfig.getCalculateConfigAttributes();
        Assert.notEmpty(calculateConfigAttributes, "计算属性列表不能为空");

        QueryWrapper<CalculateConfigAttribute> qw = new QueryWrapper<>();
        qw.eq("calculate_config_id", calculateConfig.getId());
        calculateConfigAttributeService.remove(qw);

        for (CalculateConfigAttribute calculateConfigAttribute : calculateConfigAttributes) {
            calculateConfigAttribute.setCalculateConfigId(calculateConfig.getId());
        }
        calculateConfigAttributeService.saveBatch(calculateConfigAttributes);

    }


    @Override
    public void updateStatus(CalculateConfig calculateConfig) {
        Assert.notNull(calculateConfig, "参数为空");
        Assert.notNull(calculateConfig.getStatus(), "状态不为空！");
        CalculateConfig originCalculateConfig = getById(calculateConfig.getId());
        Assert.notNull(originCalculateConfig, "原计算配置不存在");
        if (ObjectUtils.isNotEmpty(calculateConfig.getName())) {
            validRepeat(calculateConfig);
        }
        validParamFormat(calculateConfig);
        commonService.setModifyInfo(calculateConfig);
        updateById(calculateConfig);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<CalculateConfig> calculateConfigList) {
        Assert.notEmpty(calculateConfigList, "参数为空");
        List<String> ids = calculateConfigList.stream().map(CalculateConfig::getId).collect(Collectors.toList());
        removeByIds(ids);
    }

    @Override
    public List<CalculateConfig> getCalculateConfigs(String dataSourceId, String type) {
        Assert.hasLength(dataSourceId,"参数 dataSourceId 为空");
        Assert.hasLength(type,"参数useKinds 为空");
        return baseMapper.getCalculateConfigs2(dataSourceId, type);
    }
}

